package com.gang.mars.basic.classloader;

import java.io.*;

public class GangClassLoader extends ClassLoader {
    //##########################################################################################################
    //  业务要求，自定义加载类，加载自定义类
    //1) AppClassLoader 类加载器，加载的默认路径为D:\work\learn\gang-mars-java\spring-boot-basic\target\classes
    //2）GangClassLoader 自定义加载器，加载路径定义为D:\learn\gang-path-classloader
    //3）自定义类GangC.java
    //4
    //##########################################################################################################
    public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        GangClassLoader classLoader = new GangClassLoader("D:\\learn\\gang-path-classloader\\","GangClassLoader");
        Class<?> GangC = classLoader.loadClass("GangC");
        Object o = GangC.newInstance();
        System.out.println(o);
    }

    private String path;
    private String classLoaderName;

    public  GangClassLoader(String path, String classLoaderName){
        this.path = path;
        this.classLoaderName = classLoaderName;
    }

    /**
     * 重写父类ClassLoader {@link ClassLoader} findClass function
     * @param name String type, name of class
     * */
    @Override
    protected Class<?> findClass(String name) throws ClassNotFoundException {

        byte[] classByte = loadClassData(name);
        return super.defineClass(name,classByte,0,classByte.length);
    }

    /**
     * 业务意义，获取Class文件字节流数组
     * @param name class file name
     * */
    private byte[] loadClassData(String name) {
        name = path + name + ".class";

        InputStream in = null;
        ByteArrayOutputStream out=null;
        try {
            in = new FileInputStream(new File(name));
            out = new ByteArrayOutputStream();
            int i =0;
            while ((i = in.read()) != -1){
                out.write(i);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        finally {
            try {
                out.close();
                in.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return out.toByteArray();
    }
}
